package com.tj.bo.common.conf.config.bean;

import com.alibaba.fastjson.JSON;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Author: binary
 * Date: 2020/8/3 下午2:40
 */
public class StatsParamsVo {
    private static final Log LOGGER = LogFactory.getLog(StatsParamsVo.class);

    /**
     * 统计业务码
     */
    private String statsBizCode;
    /**
     * 参数模板
     */
    private List<String> replaceList;
    /**
     * 替换参数
     */
    private Map<String, String> paramsMap;
    /**
     * sql模板
     */
    private String templateSql;
    /**
     * 待执行sql
     */
    private String executeSql;
    /**
     * 结果集类型 0-单行 1-数组
     */
    private Integer resultSetType;

    public String generateSql(Map<String, Object> paramsMap) {
        String tmpSql = null;
        try {
            if (this.replaceList == null || this.replaceList.size() == 0) {
                this.setExecuteSql(this.getTemplateSql());
                return this.executeSql;
            }
            if ((paramsMap == null || paramsMap.size() == 0) && this.replaceList.size() > 0) {
                throw new ApplicationException("模板参数错误");
            }
            tmpSql = templateSql;
            for (String replace : this.replaceList) {
                String value = String.valueOf(paramsMap.get(replace));
                if (value == null) {
                    throw new ApplicationException("模板参数错误");
                }
                if (this.determineChar(value)) {
                    throw new ApplicationException("模板参数未通过校验");
                }
                tmpSql = tmpSql.replaceAll("##" + replace + "##", value);
            }
            if (tmpSql.contains("##")) {
                throw new ApplicationException("模板参数未通过校验");
            }
            this.setExecuteSql(tmpSql);
            return this.executeSql;
        } catch (ApplicationException e) {
            LOGGER.warn("业务SQL存在错误,paramsMap:{},SQL:{}", JSON.toJSONString(paramsMap), tmpSql, e);
            throw e;
        }
    }

    /**
     * 防SQL注入
     *
     * @param str
     * @return
     */
    private Boolean determineChar(String str) {
        String reg = "@@|==|--|!|;|\\!|"
                + "\\s(union|and|or|where|exec|like|from|trancate|char|substr|ascii|count|into)\\s|" +
                "\\b(select|update|delete|insert|trancate|char|alter|substr|ascii|declare|exec|drop)\\s";
        Pattern pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);//不区分大小写
        if (pattern.matcher(str).find())
            return true;
        return false;
    }

    public String getStatsBizCode() {
        return statsBizCode;
    }

    public StatsParamsVo setStatsBizCode(String statsBizCode) {
        this.statsBizCode = statsBizCode;
        return this;
    }

    public List<String> getReplaceList() {
        return replaceList;
    }

    public StatsParamsVo setReplaceList(List<String> replaceList) {
        this.replaceList = replaceList;
        return this;
    }

    public Map<String, String> getParamsMap() {
        return paramsMap;
    }

    public StatsParamsVo setParamsMap(Map<String, String> paramsMap) {
        this.paramsMap = paramsMap;
        return this;
    }

    public String getTemplateSql() {
        return templateSql;
    }

    public StatsParamsVo setTemplateSql(String templateSql) {
        this.templateSql = templateSql;
        return this;
    }

    public String getExecuteSql() {
        return executeSql;
    }

    public StatsParamsVo setExecuteSql(String executeSql) {
        this.executeSql = executeSql;
        return this;
    }

    public Integer getResultSetType() {
        return resultSetType;
    }

    public StatsParamsVo setResultSetType(Integer resultSetType) {
        this.resultSetType = resultSetType;
        return this;
    }
}
